export default class HttpRequest {

    private options: any = {
        baseUrl: 'http://127.0.0.1/',
        dataType: 'json',
        timeout: 5000,
        loading: true,
        loadingText: '加载中',
        loadingMask: true,
        responseType: 'text',
        header: {
            'Content-Type': 'application/x-www-form-urlencoded',
        },
    };

    private static mInstance: HttpRequest;

    constructor(options: any = {}) {
        this.options = Object.assign(this.options, options)
    }

    // 单例模式创建
    public static getInstance(options: any = {}): HttpRequest {
        if (!HttpRequest.mInstance) {
            HttpRequest.mInstance = new HttpRequest(options);
        }
        return HttpRequest.mInstance;
    }

    // 拦截器
    public interceptors = {
        request: (func: any) => {
            if (func) {
                HttpRequest.requestBefore = func
            }
            else {
                HttpRequest.requestBefore = (request: any) => request
            }
        },
        response: (func: any) => {
            if (func) {
                HttpRequest.requestAfter = func
            }
            else {
                HttpRequest.requestAfter = (response: any) => response
            }
        }
    }

    private static requestBefore = (config: any) => config;

    private static requestAfter = (response: any) => response;
    // 是否是完整的url路径
    private static isCompleteURL = (url: string) => /(http|https):\/\/([\w.]+\/?)\S*/.test(url);

    /**
     * 发起网络请求
     * @param options 请求参数
     * @returns Promise
     */
    private request(options: any = {}) {
        options.url = HttpRequest.isCompleteURL(options.url) ? options.url : this.options.baseUrl + options.url;
        // 合并请求参数重复则覆盖
        options = Object.assign(this.options, HttpRequest.requestBefore(options));
        if (options.loading) {
            uni.showLoading({
                title: options.loadingText,
                mask: options.loadingMask,
            })
        }
        return new Promise((resolve, reject) => {
            options.success = (res: any) => {
                resolve(HttpRequest.requestAfter(res))
            }
            options.fail = (err: any) => {
                reject(HttpRequest.requestAfter(err))
            }
            options.complete = () => {
                if (this.options.loading) {
                    uni.hideLoading()
                }
            }
            uni.request(options)
        })
    }

    private get(url: string, data: any, options: any = {}) {
        options.url = url
        options.data = data
        options.method = 'GET'
        return this.request(options)
    }

    private post(url: string, data: any, options: any = {}) {
        options.url = url
        options.data = data
        options.method = 'POST'
        return this.request(options)
    }
}